package edu.csu.smartpark.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.obs.services.model.PutObjectResult;
import edu.csu.smartpark.dao.UserDAO;
import edu.csu.smartpark.model.DO.UserDO;
import edu.csu.smartpark.model.PO.UserPO;
import edu.csu.smartpark.model.common.BusinessException;
import edu.csu.smartpark.model.common.MsgEntity;
import edu.csu.smartpark.service.UserService;
import edu.csu.smartpark.util.Constants;
import edu.csu.smartpark.util.OssUtil;
import edu.csu.smartpark.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.Arrays;
import java.util.List;

/*
* @Description: 用户相关逻辑实现类
* @Author: LZY
* @Date: 2021/4/13 19:23
*/

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDAO userDAO;

    @Autowired
    private OssUtil ossUtil;

    @Override
    public UserDO getUserById(String id) {
        QueryWrapper<UserPO> wrapper = new QueryWrapper<>();
        wrapper.eq("id", id);
        UserPO userPO = userDAO.selectOne(wrapper);
        if (userPO != null){
            UserDO userDO = new UserDO();
            BeanUtils.copyProperties(userPO, userDO);
            List<String> roles = StringUtil.splits(userPO.getRoles(),",");
            userDO.setRoles(roles);
            return userDO;
        }
        return null;
    }

    @Override
    public UserDO getUserByPhone(String phone){
        QueryWrapper<UserPO> wrapper = new QueryWrapper<>();
        wrapper.eq("phone", phone);
        UserPO userPO = userDAO.selectOne(wrapper);
        if (userPO != null){
            UserDO userDO = new UserDO();
            BeanUtils.copyProperties(userPO, userDO);
            List<String> roles = StringUtil.splits(userPO.getRoles(),",");
            userDO.setRoles(roles);
            return userDO;
        }
        return null;
    }

    @Override
    public boolean isPhoneExist(String phone){
        QueryWrapper<UserPO> wrapper = new QueryWrapper<>();
        wrapper.eq("phone", phone).select("phone");
        Integer count = userDAO.selectCount(wrapper);
        return count > 0;
    }

    public String register(UserDO userDO){
        UserPO userPO = new UserPO();
        BeanUtils.copyProperties(userDO, userPO);
        List<String> roles = userDO.getRoles();
        userPO.setRoles(StringUtil.join(roles));
        int id = userDAO.insert(userPO);
        if(id > 0){
            // 注册成功
            return userPO.getId();
        }
        return "";
    }

    @Override
    public String uploadImage(String phone, MultipartFile file) {
        // 上传图像到obs
        PutObjectResult result = ossUtil.uploadImage(file);
        if (result == null){
            log.error("upload avatar fail");
            return "";
        }
        // 将url存入数据库
        UpdateWrapper<UserPO> wrapper = new UpdateWrapper<>();
        wrapper.eq("phone", phone).set("avatar_url", result.getObjectUrl()).set("avatar_object_name", result.getObjectKey());
        userDAO.update(null, wrapper);
        return result.getObjectUrl();
    }

    @Override
    public int updatePassword(String phone, String password) {
        UpdateWrapper<UserPO> wrapper = new UpdateWrapper<>();
        wrapper.eq("phone", phone).set("encrypt_password", password);
        return userDAO.update(null, wrapper);
    }

    @Override
    public int setCompanyStaff(String donorPhone, String authorizedPhone, String companyId) {
        return 0;
    }

    @Override
    public int setFirstLevelOwnerManager(String donorPhone, String authorizedPhone, String companyId) {
        return 0;
    }

    @Override
    public int setSecondLevelOwnerManager(String donorPhone, String authorizedPhone, String companyId) {
        return 0;
    }

    @Override
    public int updateUser(UserDO userDO) {
        UserPO userPO = new UserPO();
        BeanUtils.copyProperties(userDO, userPO);
        userPO.setRoles(StringUtil.join(userDO.getRoles()));
        UpdateWrapper<UserPO> wrapper = new UpdateWrapper<>();
        wrapper.eq("phone", userDO.getPhone());
        return userDAO.update(userPO, wrapper);
    }

    @Override
    public int updatePhone(String userId, String newPhone) {
        UpdateWrapper<UserPO> wrapper = new UpdateWrapper<>();
        wrapper.eq("id", userId).set("phone", newPhone);
        return userDAO.update(null, wrapper);
    }

    @Override
    public int updateEmail(String userId, String newEmail) {
        UpdateWrapper<UserPO> wrapper = new UpdateWrapper<>();
        wrapper.eq("id", userId).set("email", newEmail);
        return userDAO.update(null, wrapper);
    }

    @Override
    /*
    * @Description: 对企业相关角色进行授权
    * @Author: LZY
    * @Date: 2021/5/28 15:45
    * @Params: [userId(授权人用户id）, authorizedPhone(被授权人电话号码), authorizeRole(授权人想要授予的给别人的角色)]
    * @Return: void
    */
    public void setEnterpriseUserRole(String userId, String authorizedPhone, String authorizeRole) throws BusinessException{
        UserDO donorUserDO = getUserById(userId);
        // 这个是兜底，大概率不会出现这个异常,除非从jwt解析出的userid有问题
        if (donorUserDO == null){
            log.error("donor user {} is not exist", userId);
            throw new BusinessException("-1", "donor user is not exist");
        }
        // 校验被授权人是否存在
        UserDO authorizedUserDO = getUserByPhone(authorizedPhone);
        if (authorizedUserDO == null){
            throw new BusinessException("-2", "authorized user is not exist");
        }
        List<String> authorizedRoles = authorizedUserDO.getRoles();
        // 如果被授权的人已拥有该角色权限，直接返回
        if (authorizedRoles.contains(authorizeRole)){
            log.info("authorized user {} have owned the role {}", authorizedUserDO.getId(), authorizeRole);
            throw new BusinessException("-5", "authorized user have owned the role");
        }
        // 如果授权人不属于任何企业，则没有授予企业角色的权限
        if (StringUtil.isEmpty(donorUserDO.getEnterpriseId())){
            log.info("donor user {} does not have permission to grant the role, because he or she does not belong to any enterprise", donorUserDO.getId());
            throw new BusinessException("-3", "donor user does not have permission to grant the role");
        }
        // 如果被授权人已属于某个企业，则需要校验授权人和被授权人是否为同一个企业
        if (!StringUtil.isEmpty(authorizedUserDO.getEnterpriseId()) &&
                !authorizedUserDO.getEnterpriseId().equals(donorUserDO.getEnterpriseId())){
            log.info("donor user {} does not have permission to grant the role, because the authorized user {} does not belongs to your enterprise {}",
                    userId, authorizedUserDO.getId(), authorizedUserDO.getEnterpriseId());
            throw new BusinessException("-3", "donor user does not have permission to grant the role");
        }
        List<String> donorUserRoles = donorUserDO.getRoles();
        // 校验是否有授予role的权限, 企业二级管理员只能由企业一级一级管理员授予,普通员工可以由一级、二级管理员授予
        if (authorizeRole.equals(Constants.SecondLevelOwnerManager) && !donorUserRoles.contains(Constants.FirstLevelOwnerManager)){
            log.info("donor user {} does not have permission to grant the role {}, because donor user have enough grant", userId, authorizeRole);
            throw new BusinessException("-3", "donor user does not have permission to grant the role");
        }else if (authorizeRole.equals(Constants.CompanyStaff) && !donorUserRoles.contains(Constants.FirstLevelOwnerManager)&&
                !donorUserRoles.contains(Constants.SecondLevelOwnerManager)){
            log.info("donor user {} does not have permission to grant the role {}, because donor user have enough grant", userId, authorizeRole);
            throw new BusinessException("-3", "donor user does not have permission to grant the role");
        }
        // 更新被授权人角色信息
        authorizedRoles.add(authorizeRole);
        authorizedUserDO.setRoles(authorizedRoles);
        authorizedUserDO.setEnterpriseId(donorUserDO.getEnterpriseId());
        updateUser(authorizedUserDO);
    }

    @Override
    public int updateEnterpriseOfUser(String userId, String enterpriseId) {
        UpdateWrapper<UserPO> wrapper = new UpdateWrapper<>();
        wrapper.eq("id", userId).set("enterprise_id", enterpriseId);
        return userDAO.update(null, wrapper);
    }
}
